﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DispatchAssist.BusinessLogical.Model;
using DispatchAssist.BusinessLogical.BLL;
using DispatchAssist.BusinessLogical.DAL;
using CarolLib.Core;
using CarolLib.WinService;
using System.Threading;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using System.Configuration;


namespace DispatchAssist.AlertMsgGenerator
{
    public class Generator : IBasicTask
    {

        #region members

        static log4net.ILog Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        private CreateAlertMsgManager manager;

        #region cache
        //private static CacheAlertRule _cacheAR;

        //public CacheAlertRule CacheAR
        //{
        //    get
        //    {
        //        if (_cacheAR == null)
        //        {
        //            try
        //            {
        //                _cacheAR = manager.GetAllAlertRule();
        //            }
        //            catch (Exception e)
        //            {
        //                Logger.Error("error in GetAllAlertRule", e);
        //            }
        //        }
        //        return _cacheAR;
        //    }
        //}

        //private static CacheEarlyTime _cacheET;

        //public CacheEarlyTime CacheET
        //{
        //    get
        //    {
        //        if (_cacheAR == null)
        //        {
        //            try
        //            {
        //                _cacheET = manager.GetAllEarlyWarn();
        //            }
        //            catch (Exception e)
        //            {
        //                Logger.Error("error in GetAllAlertRule", e);
        //            }
        //        }
        //        return _cacheET;
        //    }
        //}

        //private static CacheSeatTaiNo _cacheST;

        //public CacheSeatTaiNo CacheST
        //{
        //    get
        //    {
        //        if (_cacheST == null)
        //        {
        //            try
        //            {
        //                _cacheST = manager.GetAllSeatTailNo();
        //            }
        //            catch (Exception e)
        //            {
        //                Logger.Error("error in GetAllAlertRule", e);
        //            }
        //        }
        //        return _cacheST;
        //    }
        //}

        #endregion

        #endregion

        #region implete IBasicTask

        public void Init()
        {

            //IUnityContainer container = new UnityContainer();

            //UnityConfigurationSection config = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");

            //config.Containers["DataProvider"].Configure(container);

            //IDataProvider dp = container.Resolve<IDataProvider>();

            manager = new CreateAlertMsgManager();

        }

        public void Execute()
        {
            List<MeteoMsg> listMtMsg;

            //step1:获取最新气象报文
            try
            {
                listMtMsg = manager.GetUnCreateMeteoMsgList(Enums.MeteoMsgStatus.FinishCreateAlert,Enums.MeteoMsgStatus.CreateAlertError);
            }
            catch (Exception e)
            {
                Logger.Error("Error in GetUnCreateMeteoMsgList", e);

                return;
            }

            if (listMtMsg.Count == 0)
            {
                return;
            }


            Logger.InfoFormat("there are {0} Meteo messages", listMtMsg.Count);

            List<Alert> alertList = new List<Alert>();

            List<string> successList = new List<string>();

            List<string> failList = new List<string>();

            //step2:根据气象报文获取受影响的航班信息
            foreach (MeteoMsg mtMsg in listMtMsg)
            {

                if (string.IsNullOrEmpty(mtMsg.Airport))
                {
                    Logger.InfoFormat("there is no airport,MeteomsgID:{0}", mtMsg.MetroMsgID);

                    successList.Add(mtMsg.MetroMsgID.ToString());

                    continue;
                }

                Enums.AlertActionFlag actionFlags;
                try
                {
                    actionFlags = (Enums.AlertActionFlag)CommonCacheData.CacheAR.GetActionFlag(mtMsg.Airport, mtMsg.WarnLevel);
                }
                catch (Exception e)
                {
                    Logger.Error(string.Format("get action flag cache data error, airport :{0} warnlevel :{1}", mtMsg.Airport, mtMsg.WarnLevel), e);
                    
                    failList.Add(mtMsg.MetroMsgID.ToString());
                    
                    continue;
                }

                //该机场的报警规则中只有短信报警,则跳过
                if ((CreateAlertMsgManager.GetAlertType(actionFlags) & Enums.AlertType.CommonType) == 0)
                {
                    continue;
                }

                List<FlightInfo> listFlightInfo;
                try
                {
                    listFlightInfo = manager.GetFligetInfoByMtMsg(mtMsg.Airport, mtMsg.WarnTime.AddHours(CommonCacheData.CacheET.GetEarlyTime(mtMsg.Airport)));
                    successList.Add(mtMsg.MetroMsgID.ToString());
                }
                catch (Exception e)
                {
                    Logger.Error(string.Format("error in GetFligetInfoByMtMsg,MeteoID is {0}", mtMsg.MetroMsgID), e);

                    failList.Add(mtMsg.MetroMsgID.ToString());
                    continue;
                }

                //step3:生成预警信息
                foreach (FlightInfo fInfo in listFlightInfo)
                {
                    //add at 2011-8-2 报警时间在起飞时间前一个小时以外的,不需要发送acars

                    Enums.AlertActionFlag newActionFlag = actionFlags;
                    if ((fInfo.EstDeptTime!=null)&&(fInfo.EstDeptTime.Value.AddHours(-1) > mtMsg.WarnTime) && (fInfo.RealDeptTime == null))
                    {
                        if ((actionFlags | Enums.AlertActionFlag.ManualSendAcrarsAlert) == actionFlags)
                        {
                            newActionFlag = newActionFlag ^ Enums.AlertActionFlag.ManualSendAcrarsAlert;
                        }

                        if ((actionFlags | (Enums.AlertActionFlag.AutoSendAcarsAlert|Enums.AlertActionFlag.ConfirmAcars)) == actionFlags)
                        {
                            newActionFlag = newActionFlag ^ (Enums.AlertActionFlag.AutoSendAcarsAlert|Enums.AlertActionFlag.ConfirmAcars);
                        }
                    }

                    if ((int)newActionFlag == 0)
                    {
                        continue;
                    }
                    //end

                    Alert alertInfo = new Alert();
                    alertInfo.MetroMsgID = mtMsg.MetroMsgID;
                    alertInfo.FlightInfoID = fInfo.FlightInfoID;
                    alertInfo.AlertTime = mtMsg.WarnTime;
                    alertInfo.AirportRelation = ((Enums.AirPortRelationType)fInfo.RelationType).ToString();

                    alertInfo.AlertActionFlag = (int)newActionFlag;

                    try
                    {
                       // alertInfo.AlertActionFlag = CommonCacheData.CacheAR.GetActionFlag(mtMsg.Airport, mtMsg.WarnLevel);
                        alertInfo.SeatID = CommonCacheData.CacheST.GetSeatID(fInfo.TailNo);
                    }
                    catch (Exception e)
                    {
                        Logger.Error(string.Format("get cache seat data error in Create Alert Info, MeteoID:{0} FligtInfoID :{1} Airport :{2} TailNo:{3}",mtMsg.MetroMsgID,fInfo.FlightInfoID,mtMsg.Airport,fInfo.TailNo), e);
                        continue;
                    }

                    alertInfo.PerformActionFlag = 0;
                   

                    alertInfo.LastModifyTime = DateTime.Now;
                    alertInfo.DeleteFlag = false;

                    alertList.Add(alertInfo);
                }

            }

            //step4:插入数据
            try
            {
                manager.InsertAlertModelList(alertList);

                Logger.InfoFormat("success Create {0} message",alertList.Count);
            }
            catch (Exception e)
            {
                Logger.Error("error in InsertAlertModelList", e);
            }

            //step5:更新状态

            try
            {
                manager.UpdateMeteoStatus(successList, Enums.MeteoMsgStatus.FinishCreateAlert);
                manager.UpdateMeteoStatus(failList, Enums.MeteoMsgStatus.CreateAlertError);

                //log
                Logger.InfoFormat("MeteoMessage success {0}", successList.Count);
                Logger.InfoFormat("MeteoMessage fail {0}", failList.Count);

            }
            catch (Exception e)
            {
                Logger.Error("error in UpdateMeteoStatus", e);
            }

        }

        public void Exit()
        {

        }

        #endregion

        #region private method

        //private List<FlightInfo> CleanFlightList(List<FlightInfo> InitList, DateTime WarnTime)
        //{
        //    return InitList;

        //   InitList.Where(f=>f.a)
        //}

        #endregion
    }
}
